package com.huitong.common.mybatis.encrypt.encryptor;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import com.huitong.common.mybatis.enums.EncodeType;
import com.huitong.common.mybatis.properties.EncryptCustomProperties;

import java.nio.charset.StandardCharsets;

/**
 * SM2加密算法
 *
 * @author fromdrowning
 * @date 2024/4/13 9:43
 */
public class SM2Encryptor extends EncryptorTemplate {

    /**
     * 公钥
     */
    private final String publicKey;

    /**
     * 私钥
     */
    private final String privateKey;

    /**
     * SM2加密算法
     *
     * @param encryptCustomProperties 敏感字段加密自定义配置
     */
    public SM2Encryptor(EncryptCustomProperties encryptCustomProperties) {
        super(encryptCustomProperties);
        this.publicKey = encryptCustomProperties.getPublicKey();
        this.privateKey = encryptCustomProperties.getPrivateKey();
    }

    /**
     * 校验加密算法必要的参数配置
     */
    @Override
    public void verifyProperties() {
        if (StrUtil.isBlank(publicKey)) {
            throw new IllegalArgumentException("SM2加密需要传入公钥信息");
        }
        if (StrUtil.isBlank(privateKey)) {
            throw new IllegalArgumentException("SM2加密需要传入私钥信息");
        }
    }

    /**
     * 加密
     *
     * @param value      需要加密的敏感字段值
     * @param encodeType 加密后的编码类型
     * @return 加密后的敏感字段值
     */
    @Override
    public String encrypt(String value, EncodeType encodeType) {
        SM2 sm2 = SmUtil.sm2(null, publicKey);
        return encodeType == EncodeType.HEX ? sm2.encryptHex(value, StandardCharsets.UTF_8, KeyType.PublicKey) :
            sm2.encryptBase64(value, StandardCharsets.UTF_8, KeyType.PublicKey);
    }

    /**
     * 解密
     *
     * @param value 需要解密的敏感字段值
     * @return 解密后的敏感字段值
     */
    @Override
    public String decrypt(String value) {
        return SmUtil.sm2(privateKey, null)
            .decryptStr(value, KeyType.PrivateKey, StandardCharsets.UTF_8);
    }
}
